查看原文
其他

我才懂!SpringBoot的StringRedisTemplate与RedisTemplate的序列化策略有啥不同~

吕一明 MarkerHub 2022-11-04

小Hub领读:

StringRedisTemplate和RedisTemplate有啥不同?


前言

Redis是个高性能的K-V缓存中间件,在一些分布式场景中,可以实现多个服务之间的数据共享,并且因为容易搭建高可用的主从或集群结构,因此被广泛使用。

学习Redis,你需要懂得的知识如下:

  • Redis的五大数据类型以及常用使用场景

  • Redis的主从结构,哨兵机制

  • Redis分布式锁如何实现

  • 单线程的Redis为什么这么快?(新版本已经不是单线程了)

  • 如何解释多路复用机制

  • Redis的过期策略,内存淘汰机制

小小Redis,居然要学这么多,慢慢来吧,今天,我们就只来谈谈Springboot如何集成redis,相信有些人已经会了,当不妨来也巩固一下知识点。

Redis相关的内容,我会持续写作并发布,同学们注意置顶【MarkerHub】哈,第一时间接收内容。

集成步骤

Springboot版本:2.2.2.RELEASE

集成三步走

springboot作为一个微服务框架,及简单集成其他框架,基本上步骤相似。

  • 首先maven导入相关jar包

  • 然后编写预定配置

  • @EnableXXX实现手动装配

当然了,有些框架并不需要@EnableXXX实现手动装配,因为已经实现了自动装配,不懂Springboot手动装配和自动装配的看看这篇文章。XXX

所以集成redis步骤如下:

1、导入jar包,也可在新建项目的时候勾选Spring Data Redis,就会自动加上。

  1. <dependency>

  2. <groupId>org.springframework.boot</groupId>

  3. <artifactId>spring-boot-starter-data-redis</artifactId>

  4. </dependency>

2、编写配置,一般默认url就是localhost,端口6379,无密码。所以如果是本机的redis的话,可以省略编写配置,但为了以后上线可能修改,还是写上较好。

  1. spring:

  2. redis:

  3. host: localhost

  4. port: 6379

  5. password:

  6. database: 0

当然了,这里还有很多关于redis的优化配置项,可以自己根据实际需求调整:

  1. # 连接池最大连接数(使用负值表示没有限制)

  2. spring.redis.jedis.pool.max-active=20

  3. # 连接池最大阻塞等待时间(使用负值表示没有限制)

  4. spring.redis.jedis.pool.max-wait=-1

  5. # 连接池中的最大空闲连接

  6. spring.redis.jedis.pool.max-idle=10

  7. # 连接池中的最小空闲连接

  8. spring.redis.jedis.pool.min-idle=0

  9. # 连接超时时间(毫秒)

  10. spring.redis.timeout=1000

这时候,因为Springboot自动配置,redis就已经集成到项目中了。

我们可以使用的Redis操作工具类有两个:

  • StringRedisTemplate

  • RedisTemplate

两者的区别最大应该在这里:

  • 两者的数据是不共通的

  • StringRedisTemplate默认采用的是String的序列化策略StringRedisSerializer

  • RedisTemplate默认采用的是JDK的序列化策略JdkSerializationRedisSerializer

  • StringRedisTemplate只能对key=String,value=String的键值对进行操作,RedisTemplate可以对任何类型的key-value键值对操作

3、一般使用RedisTemplate进行数据操作。常用的接口如下:

  1. redisTemplate.opsForValue();//操作字符串

  2. redisTemplate.opsForHash();//操作hash

  3. redisTemplate.opsForList();//操作list

  4. redisTemplate.opsForSet();//操作set

  5. redisTemplate.opsForZSet();//操作有序set

测试过程:

当然了,直接使用RedisTemplate有时候不太方便,一般我们都会使用一个util工具类来封装一下,这个工具类的代码太多,我就不贴全部代码了,可以找这个链接:https://github.com/MarkerHub/eblog/blob/master/src/main/java/com/example/util/RedisUtil.java

  1. @Component

  2. public class RedisUtil {


  3. @Autowired

  4. private RedisTemplate redisTemplate;


  5. /**

  6. * 指定缓存失效时间

  7. *

  8. * @param key 键

  9. * @param time 时间(秒)

  10. * @return

  11. */

  12. public boolean expire(String key, long time) {

  13. try {

  14. if (time > 0) {

  15. redisTemplate.expire(key, time, TimeUnit.SECONDS);

  16. }

  17. return true;

  18. } catch (Exception e) {

  19. e.printStackTrace();

  20. return false;

  21. }

  22. }


  23. ....

  24. }

改变序列化策略

对象存储到redis中是需要经过序列化的过程的,这也是我们为什么需要让对象实现序列化接口 Serializable的原因,那改变序列化策略又是为了啥呢?

  • 默认序列化方式存储到redis的数据人工不可读

  • 不同策略序列化的过程有性能高低的

当然了,更多时候我们考虑的都是redis数据的可读性,因此,我们都把redis的序列化改成json或者string可读性比较强的方式。

我们先来比较一下StringRedisTemplate和RedisTemplate的序列化结果:

StringRedisTemplate序列化:

RedisTemplate序列化:

可以看出,从可读性上来讲,我们使用StringRedisTemplate操作的数据,在redis中明显更加清晰可读。

1、有哪些序列化器?

  • GenericToStringSerializer:

可以将任何对象泛化为字符串并序列化

  • Jackson2JsonRedisSerializer:

跟JacksonJsonRedisSerializer实际上是一样的

  • JacksonJsonRedisSerializer:

序列化object对象为json字符串

  • JdkSerializationRedisSerializer:

序列化java对象(被序列化的对象必须实现Serializable接口)

  • StringRedisSerializer:

简单的字符串序列化

  • GenericToStringSerializer:

类似StringRedisSerializer的字符串序列化

  • GenericJackson2JsonRedisSerializer:

类似Jackson2JsonRedisSerializer,但使用时构造函数不用特定的类参考以上序列化,自定义序列化类; 

推荐使用:

得根据场景,一般我key使用StringRedisSerializer,value使用GenericJackson2JsonRedisSerializer。

2、如何修改序列化器?

可以通过重写redisTemplate的属性改变默认序列化策略。

  1. @Bean

  2. public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {

  3. RedisTemplate<String, Object> template = new RedisTemplate();

  4. template.setConnectionFactory(redisConnectionFactory);


  5. Jackson2JsonRedisSerializer<Object> serializer = new Jackson2JsonRedisSerializer<Object>(Object.class);


  6. ObjectMapper objectMapper = new ObjectMapper();

  7. objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);

  8. objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);

  9. serializer.setObjectMapper(objectMapper);


  10. template.setKeySerializer(new StringRedisSerializer());

  11. template.setValueSerializer(serializer);


  12. template.setHashKeySerializer(new StringRedisSerializer());

  13. template.setHashValueSerializer(serializer);


  14. template.afterPropertiesSet();

  15. return template;

  16. }

测试RedisTemplate序列化效果如下:

结束语

ok,今天的文章就到此就是啦。感谢关注我的公众号:MarkerHub

(完)

MarkerHub文章索引:(点击阅读原文直达)

https://github.com/MarkerHub/JavaIndex


【推荐阅读】

Spring Boot 2 + Spring Security 5 + JWT 的单页应用 Restful 解决方案

大公司为什么都有API网关?什么是API网关?

Springboot整合多数据源以及多数据源中的事务处理(附源码)

基于消息中间件RabbitMQ实现简单的RPC服务

【项目实践】SpringBoot三招组合拳,手把手教你打出优雅的后端接口





好文!必须点赞

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存